#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "../src/struct_util.h"

#define BUFFER_SIZE 1024
#define BUFFER_OFFSET 256
static uint8_t buffer[BUFFER_SIZE] = {0};
static uint8_t backup[BUFFER_SIZE] = {0};
static int fill_value = 0;

int number_u8_pack_check()
{
    const int n = 1;
    memset(buffer, 0x55, BUFFER_SIZE);
    memset(backup, 0x55, BUFFER_SIZE);

    assert(n == struct_util_pack(buffer + BUFFER_OFFSET, ">b", 0x12));
    assert(buffer[BUFFER_OFFSET + 0] == 0x12);

    assert(0 == memcmp(buffer, backup, BUFFER_OFFSET));
    assert(0 == memcmp(buffer + BUFFER_OFFSET + n, backup + BUFFER_OFFSET + n, BUFFER_SIZE - BUFFER_OFFSET - n));
    return 0;
}
int number_u16_pack_check()
{
    const int n = 2;
    memset(buffer, 0x55, BUFFER_SIZE);
    memset(backup, 0x55, BUFFER_SIZE);

    assert(n == struct_util_pack(buffer + BUFFER_OFFSET, ">h", 0x2122));
    assert(buffer[BUFFER_OFFSET + 0] == 0x21);
    assert(buffer[BUFFER_OFFSET + 1] == 0x22);

    assert(0 == memcmp(buffer, backup, BUFFER_OFFSET));
    assert(0 == memcmp(buffer + BUFFER_OFFSET + n, backup + BUFFER_OFFSET + n, BUFFER_SIZE - BUFFER_OFFSET - n));

    return 0;
}
int number_u24_pack_check()
{
    const int n = 4;
    memset(buffer, 0x55, BUFFER_SIZE);
    memset(backup, 0x55, BUFFER_SIZE);

    assert(n == struct_util_pack(buffer + BUFFER_OFFSET, ">tb", 0x313233, 0x11)); // U24 拼包时会覆盖下一字节的垃圾数据
    assert(buffer[BUFFER_OFFSET + 0] == 0x31);
    assert(buffer[BUFFER_OFFSET + 1] == 0x32);
    assert(buffer[BUFFER_OFFSET + 2] == 0x33);

    assert(0 == memcmp(buffer, backup, BUFFER_OFFSET));
    assert(0 == memcmp(buffer + BUFFER_OFFSET + n, backup + BUFFER_OFFSET + n, BUFFER_SIZE - BUFFER_OFFSET - n));

    return 0;
}
int number_u32_pack_check()
{
    const int n = 4;
    memset(buffer, 0x55, BUFFER_SIZE);
    memset(backup, 0x55, BUFFER_SIZE);

    assert(n == struct_util_pack(buffer + BUFFER_OFFSET, ">i", 0x41424344));
    assert(buffer[BUFFER_OFFSET + 0] == 0x41);
    assert(buffer[BUFFER_OFFSET + 1] == 0x42);
    assert(buffer[BUFFER_OFFSET + 2] == 0x43);
    assert(buffer[BUFFER_OFFSET + 3] == 0x44);

    assert(0 == memcmp(buffer, backup, BUFFER_OFFSET));
    assert(0 == memcmp(buffer + BUFFER_OFFSET + n, backup + BUFFER_OFFSET + n, BUFFER_SIZE - BUFFER_OFFSET - n));

    return 0;
}
int number_u64_pack_check()
{
    const int n = 8;
    memset(buffer, 0x55, BUFFER_SIZE);
    memset(backup, 0x55, BUFFER_SIZE);

    assert(n == struct_util_pack(buffer + BUFFER_OFFSET, ">l", 0x8182838485868788ll));
    assert(buffer[BUFFER_OFFSET + 0] == 0x81);
    assert(buffer[BUFFER_OFFSET + 1] == 0x82);
    assert(buffer[BUFFER_OFFSET + 2] == 0x83);
    assert(buffer[BUFFER_OFFSET + 3] == 0x84);
    assert(buffer[BUFFER_OFFSET + 4] == 0x85);
    assert(buffer[BUFFER_OFFSET + 5] == 0x86);
    assert(buffer[BUFFER_OFFSET + 6] == 0x87);
    assert(buffer[BUFFER_OFFSET + 7] == 0x88);

    assert(0 == memcmp(buffer, backup, BUFFER_OFFSET));
    assert(0 == memcmp(buffer + BUFFER_OFFSET + n, backup + BUFFER_OFFSET + n, BUFFER_SIZE - BUFFER_OFFSET - n));

    return 0;
}
int string_pack_check()
{
    const char str[] = "hello world";
    const int n = strlen(str);
    memset(buffer, 0x55, BUFFER_SIZE);
    memset(backup, 0x55, BUFFER_SIZE);

    assert(n == struct_util_pack(buffer + BUFFER_OFFSET, "s", str)); // 自动识别字符串长度
    assert(strncmp(buffer + BUFFER_OFFSET, "12345678", n));

    assert(0 == memcmp(buffer, backup, BUFFER_OFFSET));
    assert(0 == memcmp(buffer + BUFFER_OFFSET + n, backup + BUFFER_OFFSET + n, BUFFER_SIZE - BUFFER_OFFSET - n));

    return 0;
}

int main(int argc, char const *argv[])
{
    number_u8_pack_check();
    number_u16_pack_check();
    number_u24_pack_check();
    number_u32_pack_check();
    string_pack_check();
    return 0;
}
